; isr.S - PharnOS
; Contributors: xMine
; (Any new Contributor may add himself/herself to the list)
; Changes and fixes to be made:
; Source: lowlevel.brainsware.org
;

extern idt_behandlung ; C-Funktion

; Makros - damit man nicht tausendmal den gleichen Kram schreiben muss
%macro interrupt_stub 1
global interrupt_stub_%1
interrupt_stub_%1:
    push dword 0 ; Einen pseudo-Error Code pushen, damit man überall die gleiche Funktion benutzen kann
    push dword %1
    jmp isr_common
%endmacro

; Makro für Exceptions mit Error Code
%macro interrupt_stub_error_code 1
global interrupt_stub_error_code_%1
interrupt_stub_error_code_%1:
    push dword %1
    jmp isr_common
%endmacro

; Exceptions
interrupt_stub 0
interrupt_stub 1
interrupt_stub 2
interrupt_stub 3
interrupt_stub 4
interrupt_stub 5
interrupt_stub 6
interrupt_stub 7
interrupt_stub_error_code 8
interrupt_stub 9
interrupt_stub_error_code 10
interrupt_stub_error_code 11
interrupt_stub_error_code 12
interrupt_stub_error_code 13
interrupt_stub_error_code 14
interrupt_stub 15
interrupt_stub 16
interrupt_stub_error_code 17
interrupt_stub 18
interrupt_stub 19

; IRQs - Interrupts, die von der Hardware aufgerufen werden
interrupt_stub 32
interrupt_stub 33
interrupt_stub 34
interrupt_stub 35
interrupt_stub 36
interrupt_stub 37
interrupt_stub 38
interrupt_stub 39
interrupt_stub 40
interrupt_stub 41
interrupt_stub 42
interrupt_stub 43
interrupt_stub 44
interrupt_stub 45
interrupt_stub 46
interrupt_stub 47

; System interrupt für irgendwelche Funktionalitäten
interrupt_stub 162 ; 162 => 0xA2 => 0x2A => 42 :D

; Gemeinsamer Code aller ISRs
isr_common:
	; Alle Register sichern
	pusha
	push ds
	push es
	push fs
	push gs

	; In die Datensegmente einen Kernelselektor laden, damit wir
	; garantiert mit Kernelprivilegien auf den Speicher zugreifen
	mov ax, 10h ; 10h müsste das Ring 0 Segment sein *flöt*
	mov ds, ax
	mov es, ax
	mov fs, ax
	mov gs, ax

	; ESP übergeben
	push esp
	; Aufruf der eigentlichen Behandlung
	call idt_behandlung
	; Rückgabewert in EAX nach ESP schreiben
	; -> Stack Wechsel geschieht hier
	mov esp, eax

	; Alte Registerwerte in umgekehrter Reihenfolge wiederherstellen
	pop gs
	pop fs
	pop es
	pop ds
	popa

	; User-Datensegment laden
	mov ax, 23h
	mov ds, ax
	mov es, ax

	; Fehlercode und Interruptnummer vom Stack holen
	add esp, 8


    ; Rücksprung
    iret
